feat(examples): cross-namespace agent-to-agent communication with production security governance#1908
Open
davidmarkgardiner wants to merge 1 commit into
Conversation
…duction security governance Adds a complete worked example proving A2A routing between agents in different Kubernetes namespaces via the kagent Agent Gateway, with a layered security governance stack for production use. Scenario: team-alpha/orchestrator delegates to team-beta/specialist. Files: - 00-namespaces.yaml — consumer/provider labels driving AllowedNamespaces - 01-rbac.yaml — least-privilege ServiceAccounts per namespace - 02-network-policy.yaml — default-deny + kagent-only ingress/egress - 03-secrets.yaml — API keys + delegation tokens (replace before apply) - 04-model-configs.yaml — ModelConfig CRDs per namespace - 05-specialist-agent.yaml — target agent with allowedNamespaces Selector - 06-orchestrator-agent.yaml — source agent with cross-ns tool + headersFrom - 07-verify.sh — smoke test: routing, delegation, rejection proofs - 08-istio-authz.yaml — PeerAuthentication (mTLS STRICT) + AuthorizationPolicy - 09-pod-security.yaml — Pod Security Admission restricted profile - 10-gatekeeper-policy.yaml — OPA ConstraintTemplate + Constraint - 11-cert-manager.yaml — Certificate resources for agent mTLS - 12-external-secrets.yaml — Vault-backed ExternalSecret for key rotation - 13-audit-policy.yaml — K8s audit policy targeting kagent CRDs + Secrets Security layers enforced: 1. OPA Gatekeeper — admission webhook blocks non-consumer namespace refs 2. kagent reconciler — AllowedNamespaces selector (Gateway API pattern) 3. NetworkPolicy + Istio mTLS — default-deny, SPIFFE identity enforcement 4. RBAC — agents read only own-namespace Secrets 5. headersFrom + ESO — delegation token injected, rotated from Vault daily 6. K8s audit policy — RequestResponse on CRD mutations, SIEM-ready Known gaps documented: UnsecureAuthenticator + NoopAuthorizer are dev defaults; roadmap to EP-476 OIDC/JWT and Vault PKI issuer included in README. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new examples/cross-namespace-a2a/ worked example intended to demonstrate cross-namespace Agent-to-Agent (A2A) routing via the kagent Agent Gateway along with a “layered” production security governance setup (RBAC, NetworkPolicy, Istio, Gatekeeper, cert-manager, External Secrets, audit policy).
Changes:
- Introduces cross-namespace orchestrator/specialist Agent CRs using
spec.allowedNamespacesandheadersFrom. - Adds optional governance manifests for Gatekeeper, Istio mTLS/AuthZ, cert-manager mTLS, External Secrets rotation, and apiserver audit policy.
- Adds a local verification script and README walkthrough.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/cross-namespace-a2a/README.md | End-to-end documentation for the scenario, layering model, and apply/verify steps. |
| examples/cross-namespace-a2a/00-namespaces.yaml | Creates team-alpha and team-beta namespaces with labels used by selectors/policies. |
| examples/cross-namespace-a2a/01-rbac.yaml | Example ServiceAccounts/Roles/Bindings for least-privilege secret access. |
| examples/cross-namespace-a2a/02-network-policy.yaml | Default-deny + allow rules intended to force A2A via the gateway and block pod-to-pod. |
| examples/cross-namespace-a2a/03-secrets.yaml | Placeholder secrets for model API keys and delegation token. |
| examples/cross-namespace-a2a/04-model-configs.yaml | Per-namespace ModelConfig resources referencing namespace-local secrets. |
| examples/cross-namespace-a2a/05-specialist-agent.yaml | Specialist Agent with allowedNamespaces selector allowing team=alpha. |
| examples/cross-namespace-a2a/06-orchestrator-agent.yaml | Orchestrator Agent referencing cross-namespace specialist tool with headersFrom. |
| examples/cross-namespace-a2a/07-verify.sh | Smoke test script for gateway reachability, delegation, and policy enforcement. |
| examples/cross-namespace-a2a/08-istio-authz.yaml | Optional Istio mTLS STRICT + AuthorizationPolicy enforcement. |
| examples/cross-namespace-a2a/09-pod-security.yaml | Optional Pod Security Admission restricted labels for namespaces. |
| examples/cross-namespace-a2a/10-gatekeeper-policy.yaml | Optional Gatekeeper ConstraintTemplate/Constraint for cross-namespace enforcement. |
| examples/cross-namespace-a2a/11-cert-manager.yaml | Optional cert-manager issuer/certs intended for mTLS. |
| examples/cross-namespace-a2a/12-external-secrets.yaml | Optional External Secrets Operator resources for Vault-backed rotation. |
| examples/cross-namespace-a2a/13-audit-policy.yaml | Optional apiserver audit policy for CRD mutations and secret reads. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+9
to
+11
| # Port-forward the kagent controller so we can hit the A2A gateway locally. | ||
| echo "▶ Port-forwarding kagent controller on :${CONTROLLER_PORT}…" | ||
| kubectl -n "$KAGENT_NS" port-forward svc/kagent "${CONTROLLER_PORT}:${CONTROLLER_PORT}" & |
Comment on lines
+22
to
+25
| podSelector: | ||
| matchLabels: | ||
| app.kubernetes.io/name: specialist-agent | ||
| policyTypes: |
Comment on lines
+75
to
+128
| # --- Both namespaces: allow egress only to kagent controller + kube-dns --- | ||
| apiVersion: networking.k8s.io/v1 | ||
| kind: NetworkPolicy | ||
| metadata: | ||
| name: allow-egress-to-kagent | ||
| namespace: team-alpha | ||
| spec: | ||
| podSelector: {} | ||
| policyTypes: | ||
| - Egress | ||
| egress: | ||
| - to: | ||
| - namespaceSelector: | ||
| matchLabels: | ||
| kubernetes.io/metadata.name: kagent | ||
| ports: | ||
| - protocol: TCP | ||
| port: 8083 # kagent A2A gateway port | ||
| - to: | ||
| - namespaceSelector: | ||
| matchLabels: | ||
| kubernetes.io/metadata.name: kube-system | ||
| ports: | ||
| - protocol: UDP | ||
| port: 53 # kube-dns | ||
| - protocol: TCP | ||
| port: 53 | ||
| --- | ||
| apiVersion: networking.k8s.io/v1 | ||
| kind: NetworkPolicy | ||
| metadata: | ||
| name: allow-egress-to-kagent | ||
| namespace: team-beta | ||
| spec: | ||
| podSelector: {} | ||
| policyTypes: | ||
| - Egress | ||
| egress: | ||
| - to: | ||
| - namespaceSelector: | ||
| matchLabels: | ||
| kubernetes.io/metadata.name: kagent | ||
| ports: | ||
| - protocol: TCP | ||
| port: 8083 | ||
| - to: | ||
| - namespaceSelector: | ||
| matchLabels: | ||
| kubernetes.io/metadata.name: kube-system | ||
| ports: | ||
| - protocol: UDP | ||
| port: 53 | ||
| - protocol: TCP | ||
| port: 53 |
Comment on lines
+35
to
+40
| - from: | ||
| - source: | ||
| # SPIFFE: spiffe://cluster.local/ns/kagent/sa/kagent | ||
| principals: | ||
| - "cluster.local/ns/kagent/sa/kagent" | ||
| to: |
Comment on lines
+30
to
+33
| selector: | ||
| matchLabels: | ||
| app.kubernetes.io/name: specialist-agent | ||
| action: ALLOW |
Comment on lines
+65
to
+70
| - server auth | ||
| - client auth | ||
| issuerRef: | ||
| name: kagent-ca-issuer | ||
| kind: ClusterIssuer | ||
| group: cert-manager.io |
Comment on lines
+63
to
+68
| valid_consumer_namespace(ns) { | ||
| # Namespace must carry the consumer label to make cross-ns references | ||
| # This is checked against the live namespace object via data.inventory | ||
| ns_obj := data.inventory.cluster["v1"]["Namespace"][ns] | ||
| ns_obj.metadata.labels["kagent.dev/agent-consumer"] == "true" | ||
| } |
Comment on lines
+1
to
+3
| # Kubernetes audit policy targeting kagent CRDs and A2A gateway paths. | ||
| # Mount this at the API server's --audit-policy-file flag. | ||
| # Pair with --audit-log-path and ship logs to your SIEM (Loki, Splunk, etc.) |
Comment on lines
+34
to
+36
| podSelector: | ||
| matchLabels: | ||
| app.kubernetes.io/name: kagent |
Comment on lines
+12
to
+15
| # If the specialist's allowedNamespaces selector does NOT match team-alpha, | ||
| # the controller reconciler rejects this Agent at admission and logs: | ||
| # "cross-namespace reference denied: team-alpha -> team-beta/specialist" | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
examples/cross-namespace-a2a/— a complete worked example proving A2A routing between agents in different Kubernetes namespaces via the kagent Agent Gatewayspec.allowedNamespaces(Gateway API pattern) enforced by the reconciler'sAllowsNamespace()checkUnsecureAuthenticator/NoopAuthorizer) and the roadmap to EP-476 OIDC/JWTScenario
Security layers
10-gatekeeper-policy.yamlallowedNamespacesSelector on target agent05-specialist-agent.yaml02,0801-rbac.yamlheadersFrominjects delegation token; Vault ESO rotates daily06,1213-audit-policy.yamlTest plan
kubectl apply -f examples/cross-namespace-a2a/(core files 00-06)bash examples/cross-namespace-a2a/07-verify.sh— all 5 checks pass🤖 Generated with Claude Code